package cn.edu.fzu.homemaking.company.filter.order.impl;

import cn.edu.fzu.homemaking.company.api.OrderApi;
import cn.edu.fzu.homemaking.company.domain.entity.CompanyServer;
import cn.edu.fzu.homemaking.company.domain.entity.CompanyUser;
import cn.edu.fzu.homemaking.company.domain.entity.Order;
import cn.edu.fzu.homemaking.company.domain.entity.OrderCompanyUser;
import cn.edu.fzu.homemaking.company.domain.enums.OrderStatusEnum;
import cn.edu.fzu.homemaking.company.domain.enums.ServerPriceModeEnum;
import cn.edu.fzu.homemaking.company.domain.enums.UserOrderStatusEnum;
import cn.edu.fzu.homemaking.company.filter.order.OrderFilter;
import cn.edu.fzu.homemaking.company.filter.order.OrderFilterDto;
import cn.edu.fzu.homemaking.company.filter.order.TimeDto;
import cn.edu.fzu.homemaking.company.handler.OrderSession;
import cn.edu.fzu.homemaking.company.service.CompanyServerService;
import cn.edu.fzu.homemaking.company.service.OrdersCompanyUserService;
import cn.edu.fzu.homemaking.helper.DateCycleHelper;
import cn.edu.fzu.homemaking.util.ResultUtil;
import cn.edu.fzu.homemaking.web.Result;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

/**
 * 时间冲突过滤器
 * 
 * @author fangxin
 * @date 2023年04月12日
 */
@Component("timeConflictFilter")
public class TimeConflictFilter implements OrderFilter {

    private static final String      DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";

    @Resource
    private OrdersCompanyUserService ordersCompanyUserService;

    @Resource
    private CompanyServerService     companyServerService;

    @Resource
    private OrderApi                 orderApi;

    @Override
    public boolean prepare(OrderSession session, OrderFilterDto dto) {

        TimeDto time = getTime(session.order, session.server);
        dto.orderTime = time.getCycle();

        Map<Long, String> userTimeMap = Maps.newHashMapWithExpectedSize(session.companyUsers.size());
        for (CompanyUser user : session.companyUsers) {
            List<String> orderIds = ordersCompanyUserService.listNotDoneOrderId(user.getCompanyUserId());
            List<Order> orders = ResultUtil.parseListValue(
                    orderApi.listByOrderIds(orderIds, time.getStartTime(), time.getEndTime(), OrderStatusEnum.ORDER),
                    Order.class);
            if (CollectionUtils.isEmpty(orders)) {
                continue;
            }
            List<String> date = new ArrayList<>(orders.size());
            for (Order order : orders) {
                TimeDto timeDto = getTime(order,
                        order.getServerId() == null ? null : companyServerService.getById(order.getServerId()));
                date.add(timeDto.getCycle());
            }
            userTimeMap.put(user.getCompanyUserId(), DateCycleHelper.dateMerge(date));
        }
        dto.userTimeMap = userTimeMap;
        return !userTimeMap.isEmpty();
    }


    @Override
    public boolean filter(CompanyUser user, OrderFilterDto dto) {
        String time = dto.userTimeMap.get(user.getCompanyUserId());
        return StringUtils.isNotBlank(time) && DateCycleHelper.dateConflict(time, dto.orderTime);
    }


    private TimeDto getTime(Order order, CompanyServer server) {

        String startTime = DateFormatUtils.format(order.getStartTime(), DATE_PATTERN);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(order.getStartTime());
        if (server != null && server.getChargeMode() == ServerPriceModeEnum.Times) {
            calendar.add(Calendar.HOUR_OF_DAY, order.getQty());
        } else {
            calendar.set(Calendar.HOUR, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 0);
        }
        TimeDto dto = new TimeDto();
        dto.setStartTime(startTime);
        String endTime = DateFormatUtils.format(calendar.getTime(), DATE_PATTERN);
        dto.setEndTime(endTime);

        startTime = StringUtils.substring(startTime, 11, 16);
        endTime = StringUtils.substring(endTime, 11, 16);

        dto.setCycle(DateCycleHelper.beginEndToCircle(startTime, endTime));
        return dto;
    }
}
